﻿#include "stdafx.h"
#include "RenderObject.h"

RenderObject::RenderObject()
{
	m_camera = nullptr;
	m_renders = nullptr;
	m_numRender = 0;
	m_lightIndex = -1;
	m_visible = true;
	m_color = glm::vec4(1.0f);
	SetId(0);
	m_boundBox.obj = this;
	SetBoundBox(glm::vec3(-50.0f, -50.0f, 0.f), glm::vec3(50.0f, 50.0f, 190.0f));
}

RenderObject::~RenderObject()
{
	//m_transformObject.DeleteAll();
	if (m_renders) delete[] m_renders;
}

void RenderObject::Init(Camera *camera, VaoMesh *mesh, std::vector<Material> &materials, Shader *shader)
{
	m_camera = camera;
	m_numRender = 1;
	m_renders = new Render[1];
	SetMesh(0, mesh, materials, shader);
}

void RenderObject::Init(Camera *camera, int numMesh)
{
	m_camera = camera;
	m_numRender = numMesh;
	m_renders = new Render[numMesh];
}

void RenderObject::SetMesh(int index, VaoMesh *mesh, std::vector<Material> &materials, Shader *shader)
{
	m_renders[index].SetMesh(mesh, materials, shader);
	UpdateIdColor();
}

void RenderObject::UseLight(int index)
{
	m_lightIndex = index;
}

void RenderObject::SetCamera(Camera *camera)
{
	m_camera = camera;
}

Render *RenderObject::GetRender(int index)
{
	return m_renders + index;
}

int RenderObject::GetRenderCount()
{
	return m_numRender;
}

void RenderObject::Draw()
{
	//auto did = Shaders::GetInstance()->m_drawInstDatas;
	//auto &vbo = Shaders::GetInstance()->m_vboDrawInstanceData;
	Shaders::GetInstance()->m_uboMaterial.UseLight(m_lightIndex, true);
	auto maxInst = Shaders::GetInstance()->max_uboDrawInst;
	int n = 0;
	//int count = m_transformObject.GetCount();
	DrawInstParams drawParam;
	auto &ubo = Shaders::GetInstance()->m_uboDrawInst;
	auto wm = glm::translate(GetWorldMatrix(), glm::vec3(0.0f, m_animPosOffset, 0.0f));
	//wm[3].y += m_animPosOffset;
	drawParam.Mvp = m_camera->GetProjectionMatrix() * wm;
	drawParam.ProjectionMatrix = m_camera->GetProjectionMatrix();
	drawParam.ModelViewMatrix = wm;
	drawParam.NormalMatrix = &glm::inverseTranspose(glm::mat3(wm))[0][0];
	drawParam.Color = m_color;
	ubo.SetBufferData(0, sizeof(DrawInstParams), &drawParam, true);
	auto render = m_renders;
	for (int i = 0; i < m_numRender; i++)
	{//每个模型一个渲染对象，有些模型没设置值也就没有网格
		if (render->m_vaoMesh) render->Draw(1);
		render++;
	}
	//ubo.Bind();
	//for (int i = 0; i < count; i++)
	//{
	//	TransformInfo *ti = (TransformInfo*)m_transformObject.Get(i);
	//	//did[n].mvp = m_camera->GetProjectionMatrix() * ti->GetWorldMatrix();
	//	//did[n].normalMatrix = glm::inverseTranspose(glm::mat3(ti->GetWorldMatrix()));
	//	//did[n].color = ti->GetColor();
	//	drawParam.Mvp = m_camera->GetProjectionMatrix() * ti->GetWorldMatrix();
	//	drawParam.ProjectionMatrix = m_camera->GetProjectionMatrix();
	//	drawParam.ModelViewMatrix = ti->GetWorldMatrix();
	//	drawParam.NormalMatrix = &glm::inverseTranspose(glm::mat3(ti->GetWorldMatrix()))[0][0];
	//	drawParam.Color = ti->GetColor();
	//	ubo.SetBufferData(sizeof(DrawInstParams)*n, sizeof(DrawInstParams), &drawParam, false);
	//	n++;
	//	if (n >= maxInst)
	//	{
	//		ubo.UnBind();
	//		//vbo.Update(0, sizeof(DrawInstanceData)*maxInst, did);
	//		AllRender(maxInst);
	//		ubo.Bind();
	//		n = 0;
	//	}
	//}
	//ubo.UnBind();
	//if (n)
	//{
	//	//vbo.Update(0, sizeof(DrawInstanceData)*n, did);
	//	AllRender(n);
	//}
}

void RenderObject::AllRender(int numDrawInstanced)
{
	auto render = m_renders;
	for (int i = 0; i < m_numRender; i++)
	{//每个模型一个渲染对象，有些模型没设置值也就没有网格
		if (render->m_vaoMesh) render->Draw(numDrawInstanced);
		render++;
	}
}

void RenderObject::SetColor(glm::vec4 &rgba)
{
	m_color = rgba;
}

void RenderObject::UpdateIdColor()
{
	if (!m_id) return;
	//for (int i = 0; i < m_numRender; i++)
	//{
	//	int count = m_renders[i].GetMaterialCount();
	//	for (int j = 0; j < count; j++)
	//	{
	//		auto m = m_renders[i].GetMaterial(j);
	//		if (m->m_blend) continue;
	//		m->m_materialParams.idColor = m_idColor;
	//	}
	//}
}

void RenderObject::SetId(int id)
{
	m_id = id;
	//m_boundBox.color = glm::f32_rgba_cast((glm::uint)id);
}

void RenderObject::SetBoundBox(glm::vec3 &min, glm::vec3 &max)
{
	m_boundBox.m_drawParam.bdMin = glm::vec4(min, 1);
	m_boundBox.m_drawParam.bdMax = glm::vec4(max, 1);
}

BoundBoxObject *RenderObject::GetBoundBox()
{
	m_boundBox.m_drawParam.Mvp = m_camera->GetProjectionMatrix() * GetWorldMatrix();
	return &m_boundBox;
}

void RenderObject::BoundBox::OnFocus(bool focus)
{
	obj->OnFocus(focus);
}

void RenderObject::BoundBox::OnSelect(bool select)
{
	obj->OnSelect(select);
}